package com.wtf.dsp.admin.listener;

import cn.hutool.core.net.NetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.*;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * 应用启动日志类，设置环境参数，打印启动图
 */
@Slf4j
public class SpringApplicationStartupLoggerRunListener implements SpringApplicationRunListener,Ordered {

    private final SpringApplication application;
    private final String[] args;

    public SpringApplicationStartupLoggerRunListener(SpringApplication application, String[] args) {
        this.application = application;
        this.application.setBannerMode(Banner.Mode.OFF);
        this.args = args;
    }

    private static final String LOCAL_IP_PROPERTY_KEY = "app.local.ip";
    private static final String SPRING_STARTUP_BANNER_LOCATION = "spring.startup.banner.location";
    private static final String STARTUP_BANNER_FILE = "startup-banner.txt";
    private static final String SERVER_SERVLET_CONTEXT_PATH = "server.servlet.context-path";
    private static final String SERVER_PORT = "server.port";
    private static final String LOCAL_SERVER_PORT = "local.server.port";
    private static final String SPRING_PROFILES_ACTIVE = "spring.profiles.active";

    private volatile boolean startupFlag = false;

    @Override
    public void starting() {

    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        Map<String, Object> systemProperties = environment.getSystemProperties();
        systemProperties.put(LOCAL_IP_PROPERTY_KEY, NetUtil.getLocalhost().getHostAddress());
        systemProperties.put(SPRING_STARTUP_BANNER_LOCATION, STARTUP_BANNER_FILE);
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {

    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {

    }

    @Override
    public void started(ConfigurableApplicationContext applicationContext) {
        WebApplicationType webApplicationType = this.application.getWebApplicationType();
        if(webApplicationType != null && webApplicationType != WebApplicationType.NONE && !startupFlag){
            startupFlag = true;
            ConfigurableEnvironment environment = applicationContext.getEnvironment();
            appEnvironmentPrepared(environment);
            Banner textStartUpBanner = getTextStartUpBanner(applicationContext.getEnvironment());
            textStartUpBanner.printBanner(environment, this.application.getMainApplicationClass(), System.out);
        }
    }

    private void appEnvironmentPrepared(ConfigurableEnvironment environment) {
        String server_servlet_context_path = environment.getProperty(SERVER_SERVLET_CONTEXT_PATH);
        if(!StringUtils.hasLength(server_servlet_context_path)){
            Map<String, Object> systemProperties = environment.getSystemProperties();
            systemProperties.put(SERVER_SERVLET_CONTEXT_PATH, "");
        }
        String spring_profiles_active = environment.getProperty(SPRING_PROFILES_ACTIVE);
        if(!StringUtils.hasLength(spring_profiles_active)){
            Map<String, Object> systemProperties = environment.getSystemProperties();
            systemProperties.put(SPRING_PROFILES_ACTIVE, "default");
        }
        String server_port = environment.getProperty(SERVER_PORT);
        if(!StringUtils.hasLength(server_port)){
            Map<String, Object> systemProperties = environment.getSystemProperties();
            systemProperties.put(SERVER_PORT, environment.getProperty(LOCAL_SERVER_PORT));
        }
    }


    @Override
    public void running(ConfigurableApplicationContext context) {

    }

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {

    }

    private Banner getTextStartUpBanner(Environment environment) {
        String location = environment.getProperty(SPRING_STARTUP_BANNER_LOCATION, STARTUP_BANNER_FILE);
        ResourceLoader resourceLoader =  new DefaultResourceLoader((ClassLoader)null);
        Resource resource = resourceLoader.getResource(location);
        return resource.exists() ? new ResourceBanner(resource) : null;
    }

    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE;
    }
}
